﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace BGSpaceShooter
{
    public class Router
    {
        private DisplayController DisplayController { get; set; }

        private UserInterfaceController UserInterfaceController { get; set; }

        private NetworkController NetworkController { get; set; }

        private GameObjectController GameObjectController { get; set; }

        public static GameState GameState { get; set; }

        public static string IpAddress { get; set; }
        public static int Port { get; set; }
        public static string GamePadIpAddress { get; set; }
        public static int GamePadPort { get; set; }

        public Router(GraphicsDeviceManager graphicsDeviceManager/*, string ipAddress, int port*/)
        {
            GameState = GameState.Menu;
            Camera camera = new Camera();

            DisplayController = new DisplayController(graphicsDeviceManager, camera);
            UserInterfaceController = new UserInterfaceController(camera);
            GameObjectController = new GameObjectController();
        }

        private bool Initialize()
        {

            NetworkController = new NetworkController(IpAddress, Port);

            NetworkController.RegisterStatusObservers(new List<IStatusObserver>() { GameObjectController.GameObjectContainer, UserInterfaceController });
            NetworkController.RegisterStateObservers(new List<IStateObserver>() { GameObjectController.GameObjectContainer, UserInterfaceController });

            List<ServerStatusResponse> responses;
            GameObjectController.Player = NetworkController.RegisterNewPlayer(out responses);

            if (GameObjectController.Player >= 0 && GameState == GameState.Initialize)
            {
                foreach (ServerStatusResponse serverStatusResponse in responses)
                {
                    GameObjectController.CreatePlayer(serverStatusResponse.playerId, serverStatusResponse.Position, serverStatusResponse.Rotation);
                }

                UserInterfaceController.SetActivePlayer(GameObjectController.PlayerStarFighter,
                                                        GameObjectController.GameObjectContainer.Fighters,
                                                        GameObjectController.GameObjectContainer.Projectiles);
                return true;
            }
            return false;
        }

        public void Update(GameTime gameTime)
        {
            if(GameState == GameState.Initialize)
            {
                if (Initialize())
                {
                    UserInterfaceController.StartGamePad(GamePadIpAddress, GamePadPort);
                    GameState = GameState.Game;
                }
                else
                {
                    GameState = GameState.End;
                }
            }

            if (GameState == GameState.Menu || GameState == GameState.ServerChoose || GameState == GameState.Game)
            {
                UserInterfaceController.UpdateInput(GameObjectController.GameObjectContainer.Fighters,
                                                    GameObjectController.GameObjectContainer.Projectiles);
                if (GameState == GameState.Game)
                {

                    if (GameObjectController.Player >= 0)
                    {
                        NetworkController.Update((ushort)GameObjectController.Player,
                                                 UserInterfaceController.GetInputForServer());
                        NetworkController.SendChatToServer((ushort)GameObjectController.Player,
                                                           UserInterfaceController.GetChatMessages());
                    }
                }

                UserInterfaceController.UpdateUserInterface(GameObjectController.GameObjectContainer.Fighters);
            }
        }

        public void Draw()
        {
            List<IDrawer> drawers = new List<IDrawer>();
            switch (GameState)
            {
                case GameState.Game:

                    drawers.AddRange(GameObjectController.GetGameObjectDrawers());

                    break;
            }
            drawers.AddRange(UserInterfaceController.GetDrawers(GameState));

            if(GameState == GameState.Game)
            {
                drawers.AddRange(GameObjectController.GetBillboardDrawers());
            }

            DisplayController.Draw(drawers);
        }

        public void Stop()
        {
            UserInterfaceController.Stop();
        }
    }

    public enum GameState
    {
        Initialize,
        Menu,
        ServerChoose,
        Game,
        End,
    }
}
